/* NOTICE
 
    Jim - the Java Image Manager, copyright (c) 2005 - 2007 Grant Gardner 
 
    Jim is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Jim is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
    In addition, as a special exception, you are permitted to link this code
    with the 3rd party libraries required to compile this file and to
    distribute a linked combination including them. You must obey the
    GNU General Public License in all respects for all of the code except for
    those 3rd party libraries that are licenced under terms incompatible with the
    GNU General Public License.  
 
 
 NOTICE */

package au.com.lastweekend.jim.io.exif.makernote;

import au.com.lastweekend.jim.io.exif.ExifDirectory;
import au.com.lastweekend.jim.io.exif.ExifDirectoryWriter;
import au.com.lastweekend.jim.io.exif.MetadataRuntimeException;
import au.com.lastweekend.jim.io.exif.TiffTagFormat;
import au.com.lastweekend.jim.io.exif.makernote.minolta.MinoltaMakerNoteReader;
import au.com.lastweekend.jim.io.exif.makernote.minolta.MinoltaMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.minolta.MinoltaMakernoteWriter;
import au.com.lastweekend.jim.io.metadata.Directory;

/**
 * @author <a href="mailto:grant@lastweekend.com.au"> <Grant Gardner> </a>
 * @version $Id: MakernoteRegistry.java,v 1.2 2005/06/09 11:15:36 ggardner Exp $
 */
public final class MakernoteRegistry {

    private MakernoteRegistry() throws InstantiationException {

        throw new InstantiationException("How did you get here");
    }

    /**
     * @param directory
     *            The directory containing the makernote
     * @param dataFormat
     * @param data
     *            The IFD data to which offsets refer
     * @param formatCode
     *            The format code for the makernote tag (should be Undefined)
     * @param componentCount
     *            The component count for the makernote tag
     * @param tagValueOffset
     *            The offset in the directory data
     * @TODO Make pluggable makernote readers.
     * @return a new MakernoteReader instance suitable for reading the makernote.
     */
    public static MakernoteReader getReader(ExifDirectory directory, TiffTagFormat dataFormat, byte[] data, int formatCode,
            int componentCount, int tagValueOffset) {

        String cameraMake = directory.getParentDirectory().getString(ExifDirectory.TAG_MAKE);

        if (cameraMake != null && cameraMake.length() >= 7 && "Minolta".equalsIgnoreCase(cameraMake.substring(0, 7))
                && "MLT0".equals(new String(data, tagValueOffset + 10, 4))) {
            return new MinoltaMakerNoteReader(directory, dataFormat, data, formatCode, componentCount, tagValueOffset);
        }

        // else if ("OLYMP".equals(new String(data, tagValueOffset, 5))) {
        // return new OlympusMakernoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // } else if ("Nikon".equals(new String(data, tagValueOffset, 5))) {
        // switch (data[tagValueOffset + 6]) {
        // case 1 :
        // return new NikonType1MakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // case 2 :
        // return new NikonType3MakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // default :
        // //fall through
        // }
        // } else if (cameraMake != null &&
        // cameraMake.trim().toUpperCase().startsWith("NIKON")) {
        // return new NikonType2MakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // } else if ("Canon".equalsIgnoreCase(cameraMake)) {
        // return new CanonMakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // } else if ("Casio".equalsIgnoreCase(cameraMake)) {
        // return new CasioMakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // } else if ("FUJIFILM".equals(new String(data, tagValueOffset, 8)) ||
        // "Fujifilm".equalsIgnoreCase(cameraMake)) {
        // return new FujiFilmMakerNoteReader(directory, dataFormat, data,
        // formatCode, componentCount, tagValueOffset);
        // }

        // If we get to here there is no known maker note, just read the raw
        // data so we don't lose it.
        return getUnknownMakernoteReader(directory, dataFormat, data, formatCode, componentCount, tagValueOffset);

    }

    public static MakernoteWriter getWriter(ExifDirectoryWriter parentWriter, Directory directory, int startOffset) {

        MakernoteWriter result;
        if (directory instanceof MinoltaMakernoteDirectory) {
            result = new MinoltaMakernoteWriter((MinoltaMakernoteDirectory) directory, parentWriter.getExifTransform(),
                    parentWriter.getDataFormat(), startOffset);
        } else if (directory instanceof UnknownMakernoteDirectory) {
            result = new UnknownMakernoteWriter((UnknownMakernoteDirectory) directory, startOffset);
        } else {
            throw new MetadataRuntimeException("We've read a makernote directory, but don't know how to write it");
        }

        return result;
    }

    public static MakernoteReader getUnknownMakernoteReader(ExifDirectory directory, TiffTagFormat dataFormat, byte[] data,
            int formatCode, int componentCount, int tagValueOffset) {

        return new UnknownMakernoteReader(data, formatCode, componentCount, tagValueOffset);

    }
}